import { api } from 'boot/axios';
import { AxiosRequestConfig } from 'axios';
import {
  CarListResponse,
  DriverListResponse,
  ListRequest,
  Message,
  OrderDetail,
  OrderListRequest,
  OrderListResponse,
  OrderMessage,
  Role,
  SubmitOrder,
  UserResponse,
} from 'app/typings';
import { useStore } from 'src/status';
import { Notify } from 'quasar';
import { pinia } from 'boot/config';
import { router } from 'src/router';

export function numToRole(num: number): Role {
  if (num === 0) {
    return 'user';
  } else if (num === 1) {
    return 'admin';
  }
  return 'guest';
}

export async function request(config: AxiosRequestConfig) {
  const result = await api.request(config);
  return result.data as Message;
}

export async function get(config: AxiosRequestConfig) {
  config.method = 'GET';
  return await request(config);
}

export async function post(config: AxiosRequestConfig) {
  config.method = 'POST';
  return await request(config);
}

export async function signIn(username: string, password: string) {
  const response = await post({
    url: '/account/signIn',
    params: {
      username,
      password,
    },
  });
  if (response.status === 0) {
    const user = response.data as UserResponse;
    const store = useStore(pinia);
    store.setRole(numToRole(user.type));
    store.setName(user.username);
    if (numToRole(user.type) === 'user') {
      store.setAddress(user.residence ?? '');
      store.setPhone(user.telephone ?? '');
    }
    await setMessages();
    return true;
  } else {
    Notify.create({
      message: '用户名或密码错误！',
      type: 'negative',
      position: 'top',
    });
    return false;
  }
}

export async function signOut() {
  const store = useStore(pinia);
  store.$reset();
  await post({
    url: '/account/signOut',
  });
  await router.push('/auth/login');
}

export async function signUp(username: string, password: string) {
  const response = await post({
    url: '/account/signUp',
    params: {
      username,
      password,
    },
  });
  if (response.status === -1) {
    Notify.create({
      message: '该用户名已被注册！',
      type: 'negative',
      position: 'top',
    });
    return false;
  } else {
    await signIn(username, password);
    return true;
  }
}

export async function setCurrentUser() {
  try {
    const response = await get({
      url: '/account/all',
    });
    const store = useStore(pinia);
    if (response.status === 0) {
      const user = response.data as UserResponse;
      store.setRole(numToRole(user.type));
      store.setName(user.username);
      if (numToRole(user.type) === 'user') {
        store.setAddress(user.residence ?? '');
        store.setPhone(user.telephone ?? '');
      }
    } else {
      store.$reset();
    }
  } catch (error) {}
}

export async function getUserOrderList(config: OrderListRequest) {
  const response = await get({
    url: '/user_order/list',
    params: config,
  });
  return response.data as OrderListResponse;
}

export async function getOrderDetail(id: number) {
  const response = await get({
    url: '/user_order/detail',
    params: { id },
  });
  return response.data as OrderDetail;
}

export async function receiveOrder(id: number) {
  return await post({
    url: '/user_order/receive',
    params: { id },
  });
}

export async function changeUser(updateUserMessageRequest: {
  gender?: number;
  telephone?: string;
  residence?: string;
}) {
  return await post({
    url: '/account/changeMessage',
    data: updateUserMessageRequest,
  });
}

export async function getAdminOrderList(config: OrderListRequest) {
  const response = await get({
    url: '/admin_order/list',
    params: config,
  });
  return response.data as OrderListResponse;
}

export async function getAdminOrderDetail(id: number) {
  const response = await get({
    url: '/admin_order/detail',
    params: { id },
  });
  return response.data as OrderDetail;
}

export async function getCarList(config: ListRequest) {
  const response = await get({
    url: '/car/all',
    params: config,
  });
  return response.data as CarListResponse;
}

export async function addCars(num: number) {
  return await post({
    url: '/car/add',
    params: { num },
  });
}

export async function deleteCar(id: number) {
  return await post({
    url: '/car/delete',
    params: { id },
  });
}

export async function addDrivers(num: number) {
  return await post({
    url: '/driver/add',
    params: { num },
  });
}

export async function deleteDriver(id: number) {
  return await post({
    url: '/driver/delete',
    params: { id },
  });
}

export async function getDriverList(config: ListRequest) {
  const response = await get({
    url: '/driver/all',
    params: config,
  });
  return response.data as DriverListResponse;
}

export async function getFreeCarList() {
  const response = await get({
    url: '/car/free',
    params: {
      pageNum: 0,
      pageSize: 0,
    },
  });
  return (response.data as CarListResponse).items;
}

export async function getFreeDriverList() {
  const response = await get({
    url: '/driver/free',
    params: {
      pageNum: 0,
      pageSize: 0,
    },
  });
  return (response.data as DriverListResponse).items;
}

export async function allocate(config: {
  carId: number;
  driverId: number;
  id: number;
}) {
  return await post({
    url: '/admin_order/deal',
    params: config,
  });
}

export async function searchAdminOrders(config: OrderListRequest) {
  const response = await get({
    url: '/admin_order/search',
    params: config,
  });
  return response.data as OrderListResponse;
}

export async function searchUserOrders(config: OrderListRequest) {
  const response = await get({
    url: '/user_order/search',
    params: config,
  });
  return response.data as OrderListResponse;
}

export async function submitOrder(config: SubmitOrder) {
  return await post({
    url: '/user_order/submit',
    data: config,
  });
}

export async function getUserMessages() {
  const response = await get({
    url: '/user_order/message',
  });
  return response.data as OrderMessage[];
}

export async function getAdminMessages() {
  const response = await get({
    url: '/admin_order/message',
  });
  return response.data as OrderMessage[];
}

export async function setMessages() {
  const store = useStore(pinia);
  let messages = [] as OrderMessage[];
  try {
    if (store.isUser) {
      messages = await getUserMessages();
    } else if (store.isAdmin) {
      messages = await getAdminMessages();
    }
  } catch (error) {}
  store.setMessages(messages);
}

export async function setStatus() {
  await setCurrentUser();
  await setMessages();
}
